package com.leantech.android.browser.browser.web

import android.content.Intent
import android.graphics.Bitmap
import android.net.Uri
import android.net.http.SslError
import android.os.Handler
import android.os.Looper
import android.webkit.SslErrorHandler
import android.webkit.WebResourceError
import android.webkit.WebResourceRequest
import android.webkit.WebResourceResponse
import android.webkit.WebView
import android.webkit.WebViewClient
import com.cscj.android.utils.LOG
import org.koin.core.component.KoinComponent
import java.io.ByteArrayInputStream

class RocketWebViewClient(
    private val rocketWebView: RocketWebView
) : WebViewClient(), KoinComponent {
    companion object {
        private const val TAG = "RocketWebViewClient"
        private const val MSG_PAGE_FINISHED = 1
        private const val DELAY = 500L
    }

    private val webContentPostProcessor = WebContentProcessor()
    private val context = rocketWebView.context
    private val handler = Handler(Looper.getMainLooper()) { msg ->
        when (msg.what) {
            MSG_PAGE_FINISHED -> {
                val url = msg.obj as String
                val historyList = rocketWebView.copyBackForwardList()
                rocketWebView.webViewCallback?.onUrlChanged(
                    rocketWebView.title ?: "", url, historyList
                )
                rocketWebView.webViewCallback?.onAddBrowserHistory(
                    rocketWebView.title ?: "", url, rocketWebView.favicon
                )
                LOG.d(TAG, "onAddBrowserHistory title ${rocketWebView.title} , url $url")
                true
            }

            else -> {
                false
            }
        }
    }

    //广告过滤
    private val adTxtResponse: WebResourceResponse = WebResourceResponse(
        "text/plain", "utf-8", ByteArrayInputStream("".toByteArray())
    )

    override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
        super.onPageStarted(view, url, favicon)
        LOG.d(TAG, "onPageStarted url $url, originUrl ${view?.originalUrl}")
    }

    override fun onPageFinished(view: WebView, url: String) {
        rocketWebView.updateCssStyle()
        //inject reader
        webContentPostProcessor.postProcess(rocketWebView, url)
        LOG.d(
            TAG,
            "onPageFinished title ${view.title} progress ${view.progress} url $url , originUrl ${view.originalUrl}"
        )


        if (view.progress >= 100) {
            handler.removeMessages(MSG_PAGE_FINISHED) //remove previous msg
            val msg = handler.obtainMessage(MSG_PAGE_FINISHED, url)
            handler.sendMessageDelayed(msg, DELAY)
        }

        clearHistoryIfPossible()
    }


    override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
        LOG.d(
            TAG,
            "shouldOverrideUrlLoading isRedirect ${request.isRedirect} header ${request.requestHeaders}"
        )
        return handleUri(view, request.url)
    }

    override fun shouldInterceptRequest(
        view: WebView, request: WebResourceRequest
    ): WebResourceResponse? {
        val uri = request.url
        if (uri.host == "222.186.175.19") { //block ad
            return adTxtResponse
        }
        return super.shouldInterceptRequest(view, request)
    }

    private fun handleUri(webView: WebView, uri: Uri): Boolean {
        val url = uri.toString()
        LOG.d(TAG, "handleUri $url , originUrl ${webView.originalUrl}")

        if (url.startsWith("http")) {
            return false
        }

        if (rocketWebView.config.blockIntent) {//阻拦第三方App
            return true
        } else {
            val intent = uriToIntent(webView, uri)
            if (intent == null) {
                return true
            } else {
                val chain = object : IntentBlockChain {
                    override fun proceed() {
                        try {
                            context.startActivity(intent)
                        } catch (e: Exception) {
                            LOG.e(TAG, "intent can not be resolved", e)
                        }
                    }

                    override fun cancel() {

                    }
                }

                rocketWebView.webViewCallback?.onBlockIntent(chain)
            }
        }

        return true
    }

    private fun uriToIntent(webView: WebView, uri: Uri): Intent? {
        val url = uri.toString()
        val viewIntent = Intent(Intent.ACTION_VIEW).setData(uri)
        val pm = context.packageManager
        if (viewIntent.resolveActivity(pm) != null) {
            return viewIntent
        }

        if (url.startsWith("intent:")) {
            val intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME)
            if (intent.resolveActivity(pm) != null) {
                return intent
            }
            val fallbackUrl = intent.getStringExtra("browser_fallback_url")
            if (fallbackUrl != null) {
                if (fallbackUrl.startsWith("market://")) {
                    val fallbackIntent = Intent.parseUri(fallbackUrl, Intent.URI_INTENT_SCHEME)
                    if (fallbackIntent.resolveActivity(pm) != null) {
                        return fallbackIntent
                    }
                } else {
                    webView.loadUrl(fallbackUrl)
                }
            }
        }

        return null
    }


    interface IntentBlockChain {
        fun proceed()

        fun cancel()
    }

    private fun clearHistoryIfPossible() {
        rocketWebView.postDelayed({
            if (rocketWebView.clearHistory) {
                rocketWebView.clearHistory = false
                rocketWebView.clearHistory()
            }
        }, 500)
    }

    override fun onReceivedError(
        view: WebView?, request: WebResourceRequest?, error: WebResourceError?
    ) {
        //如果https不行，使用http重试
        if (error?.description == "net::ERR_SSL_PROTOCOL_ERROR" && request != null) {
            rocketWebView.loadUrl(request.url.buildUpon().scheme("http").build().toString())
        } else {
            LOG.e(
                TAG,
                "onReceivedError: ${request?.url} , code: ${error?.errorCode} error: ${error?.description}"
            )
        }

        clearHistoryIfPossible()

    }


    override fun onReceivedSslError(view: WebView, handler: SslErrorHandler, error: SslError) {
        var message = """"SSL Certificate error.""""
        when (error.primaryError) {
            SslError.SSL_UNTRUSTED -> message = """"Certificate authority is not trusted.""""
            SslError.SSL_EXPIRED -> message = """"Certificate has expired.""""
            SslError.SSL_IDMISMATCH -> message = """"Certificate Hostname mismatch.""""
            SslError.SSL_NOTYETVALID -> message = """"Certificate is not yet valid.""""
            SslError.SSL_DATE_INVALID -> message = """"Certificate date is invalid.""""
            SslError.SSL_INVALID -> message = """"Certificate is invalid.""""
        }

        LOG.e(TAG, "onReceivedSslError: $message")

        handler.proceed()
    }
}